<?php
/**
 * @abstract 配置类
 * 
 * @author zhoujing
 */
class Config
{
	private static $singleton = null;
	private $_loaded = array();
	
	public static function init()
	{
		if(self::$singleton == null)
		{
			self::$singleton = new Config();
		}
	
		return self::$singleton;
	}
	
	private function __construct()
	{
		//需要自动加载的配置文件
		$this->items('config');
		$this->items('router');
	}
	
	/**
	 * 获取某一种类型配置的所有数据
	 * 
	 * @param string $type 配置类型
	 * @return array
	 */
	public function items($type = 'config')
	{
		$type = strtolower($type);
		if(!isset($this->_loaded[$type]))
		{
			if(!file_exists(APP.'/config/'.$type.'.php'))
			{
				sys_error('配置文件 [ {1} ] 不存在。', APP.'/config/'.$type.'.php');
			}
			
			require(APP.'/config/'.$type.'.php');
			if(!isset($$type) || !is_array($$type))
			{
				sys_error('配置文件 [ {1} ] 的配置项必须为数组类型，且数组名必须为 [ {2} ]', array(
					APP.'/config/'.$type.'.php', '$'.$type
				));
			}
			
			$this->_loaded[$type] = $$type;
			unset($$type);
		}
		
		return $this->_loaded[$type];
	}
	
	/**
	 * 获取配置项
	 * 
	 * @param string $name 配置项名称
	 * @param string $type 配置类型，默认为config
	 * 
	 * @return mixed 返回配置项
	 */
	public function get($name, $type = "config")
	{
		//若配置项来自主配置文件，则直接读
		if($type === 'config')
		{
			if(!isset($this->_loaded['config'][$name]))
			{
				sys_error("配置文件 [ {1} ] 中配置项 [ {2} ] 不存在", array(
					APP.'/config/'.$type.'.php', '$config["'.$name.'"]'		
				));
			}
			
			return $this->_loaded['config'][$name];
		}
		
		//判断配置项是否已加载入内存，若已加载则直接读 
		if(isset($this->_loaded[$type]))
		{
			if(!isset($this->_loaded[$type][$name]))
			{
				sys_error("配置文件 [ {1} ] 中配置项 [ {2} ] 不存在", array(
					APP.'/config/'.$type.'.php', '$config["'.$name.'"]'		
				));
			}
			
			return $this->_loaded[$type][$name];
		}
		
		//现在开始从文件中读取配置项
		$this->items($type);
		if(!isset($this->_loaded[$type][$name]))
		{
			sys_error("配置文件 [ {1} ] 中配置项 [ {2} ] 不存在", array(
				APP.'/config/'.$type.'.php', '$config["'.$name.'"]'		
			));
		}
		
		return $this->_loaded[$type][$name];
	}
	
	/**
	 * 设置配置项
	 * 
	 * @param array $map 键值对对应的配置项
	 * @param string $type 配置类型
	 * 
	 * @return bool
	 */
	public function set($map, $type = 'config')
	{
		if(!is_array($map) || empty($map))
		{
			return false;
		}
		
		//配置类型尚未加载，先加载
		$this->items($type);
		
		//保证配置项在内存中之后再设置
		foreach($map as $key=>$value)
		{
			$this->_loaded[$type][$key] = $value;
		}
		
		return true;
	}
}